<script lang="ts" setup>
import { h, ref, onMounted, computed, reactive } from 'vue';
import { IconStar, IconFile, IconMore, IconPlus, IconFolder } from '@arco-design/web-vue/es/icon';
import { Message, TreeNodeData } from '@arco-design/web-vue';
import { activity, errors, upload } from '@/api';
import dateFormat from 'ourwill-feutil/common/dateFormat';

interface FileInfo {
	fileText: string;
	isRelease?: number;
	pictureParams?: string;
}

/**
 * fileName: "产品简介"
 * fileType: 0
 * id: 1
 * pid: 0
 * sortNum: 1,
 * key: 1,
 *
 */
const treeData: any = ref([]);

let contentInfo = reactive({
	id: '',
	pid: '',
	fileName: '',
	content: '',
	updateTime: '',
});
const wordCount = ref(0);

const treeRef = ref();
const nameInputRefs = ref();
const editorRefs = ref();

const inputValue = ref('');

const removeKey = ref('');
const removeVisible = ref(false);

const fixTitle = ref(false);
const contentTitleRefs = ref();
const currentNode = reactive({
	id: '',
	title: '',
});

let pictureParams: any[] = [];

const showNodeTitle = computed(() => {
	return currentNode.id && currentNode.title ? currentNode.title : '';
});

const toolbar = {
	video: {
		title: '上传视频',
		icon: 'v-md-icon-video',
		menus: {
			mode: 'list',
			itemWidth: '100px',
			rowNum: 1,
			items: [
				{
					text: '上传本地视频',
					action(editor: any) {
						const videoInput = document.createElement('input');
						videoInput.type = 'file';
						videoInput.accept = 'video/*';
						// 添加事件监听器，当选择了视频文件后触发
						videoInput.addEventListener('change', async (event: any) => {
							const file = event.target.files[0];
							const { ok, data } = await upload.uploadVideo(file);
							if (!ok) {
								return;
							}

							const res = data.data;

							editor.insert(() => {
								const videoUrl = `<video style='width: 100%; height: auto;' data-name='${res.filename}' src='${res.url}' controls></video>`;
								return {
									text: `${videoUrl}`,
								};
							});
						});

						videoInput.click();
					},
				},
			],
		},
	},
};

// 获取帮助中心菜单树
const getHelpTreeList = async () => {
	const { data, ok } = await activity.getHelpTreeList();
	if (!ok) {
		return;
	}
	treeData.value = fixTreeField(data.data.menuData);
};

// 调整帮助中心树的结构
const fixTreeField = (tree: Array<any>): any => {
	let ret = [];
	ret = tree.map((item: any) => {
		let icon = item.fileType ? () => h(IconFile) : () => h(IconFolder);
		let children = [];
		if (item.children && item.children.length) {
			children = fixTreeField(item.children);
		}
		return {
			...item,
			key: item.id,
			title: item.fileName,
			children: children,
			icon,
		};
	});
	return ret;
};

// 树结点 点击
const select = (selectedKeys: any, data: any) => {
	if (data.node.fileType) {
		const { id, title } = data.node;
		currentNode.id = id;
		currentNode.title = title;
		getFileContent(id);
	}
};

// 获取文章内容
const getFileContent = async (id: number | string) => {
	const { data, ok } = await activity.getFileContent(id);
	if (!ok) {
		return;
	}
	if (data.data && data.data.oneData) {
		const { oneData } = data.data;
		const { id, pid, fileName, fileText, updateTime } = oneData;
		contentInfo.id = id;
		contentInfo.pid = pid;
		contentInfo.fileName = fileName;
		contentInfo.content = fileText ? fileText : '';
		contentInfo.updateTime = updateTime;
	}
};

// 内容更新
const updateFileOrFolder = async (id: number | string, info: any) => {
	const { data, ok } = await activity.updateFileOrFolder(id, info);
	if (!ok) {
		return;
	}

	Message.success(data.msg);
};

// 保存或发布
const saveFileContent = (isRelease: number) => {
	// 如果没有内容，禁止保存和发布
	if (!contentInfo.id) {
		Message.error('请选择需要编辑的文档后，进行保存或发布操作');
		return;
	}

	const id = contentInfo.id;
	const fileText = contentInfo.content;

	const info: FileInfo = {
		fileText,
		isRelease,
	};

	if (pictureParams && pictureParams.length) {
		info.pictureParams = pictureParams.join(',');
	}

	updateFileOrFolder(id, info);
};

const fixContentTitle = () => {
	fixTitle.value = true;
	setTimeout(() => {
		contentTitleRefs.value.focus();
	}, 100);
};

const contentTitleBlur = () => {
	const id = currentNode.id;
	const info = {
		fileName: currentNode.title,
	};

	updateFileOrFolder(id, info);

	fixTitle.value = false;

	let ret;

	let len = treeData.value.length;

	for (let i = 0; i < len; i++) {
		ret = findTreeNode(treeData.value[i], id);
		if (ret) {
			ret.title = currentNode.title;
			break;
		}
	}
};

// 重命名
const reName = (nodeData: any) => {
	nodeData.isRename = true;

	setTimeout(() => {
		nameInputRefs.value.focus();
		inputValue.value = nodeData.title;
	}, 10);
};

const closeInput = async (nodeData: any) => {
	if (!inputValue.value) {
		Message.warning('文件名不能为空');
		nameInputRefs.value.focus();
	} else {
		const id = nodeData.id;
		const info = {
			fileName: inputValue.value,
		};
		await updateFileOrFolder(id, info);

		nodeData.isRename = false;
		nodeData.isNew = false;
		nodeData.title = inputValue.value;
	}
};

// 查找当前节点
const findTreeNode = (tree: any, id: number | string): any => {
	if (tree.id === id) {
		return tree;
	}

	let len = tree.children && tree.children.length;

	for (let i = 0; i < len; i++) {
		const child = tree.children[i];
		const node = findTreeNode(child, id);

		if (node) {
			return node;
		}
	}
};

// 新建文件
const newFile = async (nodeData: any) => {
	const { id } = nodeData;

	const formData = {
		pid: id,
		fileType: 1,
		// fileName: '新建文件',
	};

	const { data, ok } = await activity.saveFileOrFolder(formData);

	if (!ok) {
		return;
	}

	Message.success(data.msg);

	const node = {
		...data.data,
		title: data.data.fileName,
		key: data.data.id,
		isNew: true,
		icon: () => h(IconFile),
	};

	if (id == 0) {
		treeData.value.push(node);
	} else {
		if (!nodeData.children || !Array.isArray(nodeData.children)) {
			nodeData.children = [];
		}
		nodeData.children.push(node);
	}

	inputValue.value = node.title;

	expandNode(nodeData.key);
	setTimeout(() => {
		nameInputRefs.value.focus();
	}, 10);
};

// 新建文件夹
const newFolder = async (nodeData: any) => {
	const { id } = nodeData;

	const formData = {
		pid: id,
		fileType: 0,
		// fileName: '新建文件夹',
	};

	const { data, ok } = await activity.saveFileOrFolder(formData);

	if (!ok) {
		return;
	}

	Message.success(data.msg);

	const node = {
		...data.data,
		title: data.data.fileName,
		key: data.data.id,
		isNew: true,
		icon: () => h(IconFolder),
	};

	// 根节点进行单独处理
	if (id == 0) {
		treeData.value.push(node);
	} else {
		if (!nodeData.children || !Array.isArray(nodeData.children)) {
			nodeData.children = [];
		}
		nodeData.children.push(node);
	}

	inputValue.value = node.title;
	expandNode(nodeData.key);
	setTimeout(() => {
		nameInputRefs.value.focus();
	}, 10);
};

//展开指定节点
const expandNode = (key: string) => {
	setTimeout(() => {
		treeRef.value.expandNode(key, true);
	}, 10);
};

// 删除文件或文件夹
const toRemove = (nodeData: any) => {
	removeVisible.value = true;
	removeKey.value = nodeData.key;
};

const removeNode = async () => {
	const { data, ok } = await activity.deleteFileOrFolder(removeKey.value);
	if (!ok) {
		return;
	}
	deleteLoop(treeData.value, removeKey.value);
	removeVisible.value = false;
	Message.success(data.msg);
};

const deleteLoop = (arr: any, deleteKey: string) => {
	arr.forEach((item: any, index: number) => {
		if (item.key === deleteKey) {
			arr.splice(index, 1);
		} else if (item.children && item.children.length > 0) {
			return deleteLoop(item.children, deleteKey);
		}
	});
};

// 时间过滤
const filterUpdateTime = (val: number | string) => {
	if (!val) {
		return '--';
	}

	return dateFormat(val, 'YYYY-MM-DD HH:mm:ss');
};

// 拖拽执行
const onDrop = async ({ dragNode, dropNode, dropPosition }: { dragNode: any; dropNode: any; dropPosition: number }) => {
	/**
	 * dragNode：当前的拖拽节点
	 * dropNode：目标节点
	 */

	const sourceId = dragNode.id;
	const targetId = dropNode.id;

	const { data, ok } = await activity.dropFileOrFolder(sourceId, targetId, dropPosition);
	if (!ok) {
		return;
	}

	Message.success(data.msg);

	const loop = (data: any, key: any, callback: any) => {
		data.some((item: any, index: number, arr: any) => {
			if (item.key === key) {
				callback(item, index, arr);
				return true;
			}
			if (item.children) {
				return loop(item.children, key, callback);
			}
			return false;
		});
	};

	loop(treeData.value, dragNode.key, (_: any, index: number, arr: any) => {
		arr.splice(index, 1);
	});

	if (dropPosition === 0) {
		loop(treeData.value, dropNode.key, (item: any) => {
			item.children = item.children || [];
			item.children.push(dragNode);
		});
	} else {
		loop(treeData.value, dropNode.key, (_: any, index: number, arr: any) => {
			arr.splice(dropPosition < 0 ? index : index + 1, 0, dragNode);
		});
	}
};

// 拖拽时不允许在文件类型节点上释放
const allowDrop = (e: any) => {
	let bol = true;
	if (e.dropNode.fileType && e.dropPosition === 0) {
		bol = false;
	}
	return bol;
};

// 上传图片
const handleUploadImage = async (event: any, insertImage: any, files: any) => {
	const fileData = await uploadImg(files[0]);

	pictureParams.push(fileData.data);

	insertImage({
		url: fileData.url,
	});
};

const uploadImg = async (fileData: any) => {
	const file = fileData;
	const isLtScreen = file.size / 1024 / 1024 < 5;
	if (!isLtScreen) {
		Message.error('图片大小不能超过2MB!');
		return;
	}
	try {
		const { data, ok } = await upload.uploadImg(file);
		if (!ok) {
			return;
		}
		Message.success('上传成功');
		return data.data ? data.data : null;
	} catch (error) {
		errors(error);
	}
};

// 预览区返回顶部
const scrollPreviewToTop = () => {
	editorRefs.value.previewScrollTo(0);
};

const onChange = (html: any) => {
	wordCount.value = html.length;
};

getHelpTreeList();
</script>

<template>
	<div class="help-header">
		<span class="header-title"> 帮助中心管理 </span>
		<div class="operation-btn">
			<a-button @click="saveFileContent(0)">
				<template #icon>
					<icon-save />
				</template>
				<template #default>保存</template>
			</a-button>
			<a-button type="primary" @click="saveFileContent(1)">
				<template #icon>
					<icon-share-external />
				</template>
				<template #default>发布</template>
			</a-button>
		</div>
	</div>
	<div class="help-main">
		<div class="help-left">
			<span class="left-title">帮助中心</span>
			<a-dropdown>
				<IconPlus class="icon-add" style="float: right; margin-top: 3px" />
				<template #content>
					<a-doption @click="newFile({ id: 0 })">新建文档</a-doption>
					<a-doption @click="newFolder({ id: 0 })">新建文件夹</a-doption>
				</template>
			</a-dropdown>

			<a-tree
				ref="treeRef"
				class="help_tree"
				:data="treeData"
				draggable
				:allow-drop="allowDrop"
				@drop="onDrop"
				@select="select"
			>
				<template #icon>
					<IconStar />
				</template>

				<template #extra="nodeData">
					<a-dropdown>
						<IconMore class="more-action" style="font-size: 20px" />
						<template #content>
							<a-doption v-show="!nodeData.fileType" @click="newFile(nodeData)">新建文档</a-doption>
							<a-doption v-show="!nodeData.fileType" @click="newFolder(nodeData)">新建文件夹</a-doption>
							<!-- <a-doption :value="{ value: 'Option3' }">创建副本</a-doption> -->
							<a-doption @click="reName(nodeData)">重命名</a-doption>
							<a-doption @click="toRemove(nodeData)">删除</a-doption>
						</template>
					</a-dropdown>
				</template>

				<template #title="nodeData">
					<a-input
						v-if="nodeData.isRename || nodeData.isNew"
						ref="nameInputRefs"
						v-model="inputValue"
						:style="{ width: 'auto', height: '26px' }"
						placeholder="请输入"
						@blur="closeInput(nodeData)"
					/>
					<span v-else>{{ nodeData.title }}</span>
				</template>
			</a-tree>
		</div>

		<div v-if="showNodeTitle" class="help-right">
			<div v-if="!fixTitle" class="content-title" @click="fixContentTitle">
				{{ showNodeTitle }}
			</div>
			<div v-else class="content_title_input">
				<a-input
					ref="contentTitleRefs"
					v-model="currentNode.title"
					style="width: 50%"
					@blur="contentTitleBlur"
				/>
			</div>
			<div class="rencent-edit">
				<span>最近编辑：</span>
				<span>{{ filterUpdateTime(contentInfo.updateTime) }}</span>
			</div>

			<v-md-editor
				ref="editorRefs"
				v-model="contentInfo.content"
				height="calc(100vh - 229px)"
				left-toolbar="undo redo clear | h bold italic strikethrough quote | ul ol table hrul ol table hr | link image video code"
				:disabled-menus="[]"
				:toolbar="toolbar"
				@upload-image="handleUploadImage"
				@change="onChange"
			/>
			<div class="content-footer">
				<span>字数：{{ wordCount }} / 50000</span>
				<span style="cursor: pointer" @click="scrollPreviewToTop">返回顶部</span>
			</div>
		</div>
		<div v-else class="help_right_empty">
			<a-empty> 请选择需要编辑的文档 </a-empty>
		</div>

		<a-modal v-model:visible="removeVisible" title-align="start" @cancel="removeVisible = false">
			<template #title> 确认删除 </template>
			确认删除该文件或文件夹吗？
			<template #footer>
				<a-button @click="removeVisible = false">取消</a-button>
				<a-button type="primary" @click="removeNode">确定</a-button>
			</template>
		</a-modal>
	</div>
</template>

<style lang="less">
.help-header {
	display: flex;
	justify-content: space-between;
	padding: 18px;
	border-bottom: 1px solid #e5e6e8;

	.header-title {
		font-size: 18px;
		font-weight: 600;
		line-height: 32px;
	}

	.operation-btn {
		.arco-btn:nth-child(2) {
			margin-left: 10px;
		}
	}
}

.help-main {
	display: flex;
	width: 100%;
	.help-left {
		padding: 18px;
		// width: 300px;
		width: 292px;
		flex-shrink: 0;
		overflow: hidden;
		min-height: calc(100vh - 129px);
		background: #f4f5f7;
		.help_tree.arco-tree {
			.arco-tree-node {
				width: 256px;
				.arco-tree-node-title {
					width: 50px;
					flex-grow: 1;
					.arco-tree-node-title-text {
						width: 100%;
						white-space: nowrap;
						overflow: hidden;
						text-overflow: ellipsis;
						.arco-tree-node-drag-icon {
							display: none;
						}
					}
				}
			}
		}

		.icon-add {
			font-size: 20px;
			padding: 4px;
		}

		.icon-add:hover {
			background: #eaeaea;
			cursor: pointer;
		}

		.left-title {
			font-size: 14px;
			font-weight: 500;
		}

		.more-action {
			padding: 3px;
		}

		.more-action:hover {
			background: #eaeaea;
		}
	}

	.help-right {
		width: 100%;
		padding: 20px 45px 0px 32px;

		.content-title {
			font-size: 16px;
			font-weight: 500;
		}

		.rencent-edit {
			color: #bfbfbf;
			font-size: 12px;
		}

		.v-md-editor {
			width: 100%;
			.v-md-editor__toolbar-item-save {
				display: none !important;
			}
		}

		.content-footer {
			padding: 0px 5px;
			height: 32px;
			line-height: 32px;
			border: 1px solid #eee;
			display: flex;
			justify-content: space-between;
			color: #808080;
			font-size: 12px;
		}
	}
	.help_right_empty {
		width: 100%;
		display: flex;
		align-items: center;
		justify-content: center;
	}
}

.v-md-editor__toolbar-item.v-md-icon-save.v-md-editor__toolbar-item-save {
	display: none !important;
}
</style>
